true.

flip(heads).
flip(tails).

':-'(op(1200,fx,':-')).

:- op(700,xfx,'=').
X = X.

:- op(1200,xfx,':-').
call(X) :- X.

:- op(1000,xfy,',').
(X,Y) :- X, Y.

:- op(900,fy,'\+').
\+ X :- call(X), !, fail.
\+ X.

:- op(700,xfx,'\=').
X \= Y :- \+ X = Y.

:- op(1025,xfx,'=>').
This => That :- \+ (call(This), \+ call(That)).

:- op(700,xfx,'==').
V1 == V2 :-
  var(V1), var(V2),
  \+ (V1 = chalk, V2 = cheese).
C1 == C2 :-
  functor(C1, C, N), functor(C2, C, N),
  ( arg(I,C1,A1),arg(I,C2,A2) => A1 == A2 ).

member(E,[E|_]).
member(E,[_|Es]) :- member(E,Es).

memq(X,[X1|_]) :- X == X1.
memq(X,[_|Xs]) :- memq(X,Xs).

append([],Ys,Ys).
append([X|Xs],Ys,[X|Zs]) :- append(Xs,Ys,Zs).

:- op(700,xfx,'-').

split([Sep|RHS], Sep, []-RHS).
split([Head|Tail], Sep, [Head|LHS]-RHS) :- split(Tail, Sep, LHS-RHS).

filter(_,[],[]).
filter(E,[E|Es],Fs) :- filter(E,Es,Fs).
filter(E,[F|Es],[F|Fs]) :- E \= F, filter(E,Es,Fs).

sort(Key,List,Sorted) :- qsort(Key,List,Sorted,[]).

qsort(Key,[X|L],R,R0) :-
 partition(Key,L,X,L1,L2),
 qsort(Key,L2,R1,R0),
 qsort(Key,L1,R,[X|R1]).
qsort(_,[],R,R).

:- op(700,xfx,'>=').

partition(Key,[X|L],Y,[X|L1],L2) :-
 apply(Key,[X,Xk]), apply(Key,[Y,Yk]), Xk >= Yk, !,
 partition(Key,L,Y,L1,L2).
partition(Key,[X|L],Y,L1,[X|L2]) :-
 partition(Key,L,Y,L1,L2).
partition(_,[],_,[],[]).

:- op(400,yfx,'/').

:- dynamic('$foo$term_expansion'/2).
'$foo$expand_term'(Term, Expansion) :- '$foo$term_expansion'(Term, Expansion), !.
'$foo$expand_term'(Term, Term).


:- op(700,xfx,'=..').

